<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ELK-BLEDOB</title>
<script>
var writer = null, history = {},buffer = null,$ = document.querySelector.bind(document);
var device = {}, fwFile = null, deviceInfo = {
	color: null,
	bright: null,
	effect: null,
	on: null,
	off: null,
}, effects = {
	135:"three color jump",
	136:"seven color jump",
	137:"three color cross fade",
	138:"seven color cross fade",
	139:"red fade",
	140:"green fade",
	141:"blue fade",
	142:"yellow fade",
	143:"cyan fade",
	144:"magenta fade",
	145:"white fade",
	146:"red green cross fade",
	147:"red blue cross fade",
	148:"green blue cross fade",
	149:"seven color strobe flash",
	150:"red strobe flash",
	151:"green strobe flash",
	152:"blue strobe flash",
	153:"yellow strobe flash",
	154:"cyan strobe flash",
	155:"magenta strobe flash",
	156:"white strobe flash",
},cmds = {
	"on":           x=>[126,7,4,255,0,1,2, 1,239],
	"off":          x=>[126,7,4,  0,0,0,2, 1,239],
	"colorRGB":       x=>[126,7,5,  3,x[0]%256,x[1]%256,x[2]%256,16,239],
	"color":        x=> [126,7,5,  3,parseInt(x[1]+x[2],16),parseInt(x[3]+x[4],16),parseInt(x[5]+x[6],16),16,239],
	"bright":       x=>[126,4,1,  x%101,1,255,2,1,239],
	"effect":       x=>[126,7,3,  x%256,3,255,255,0,239],
	"speed":        x=>[126,7,2,  x%256,3,255,255,0,239],
};
function setDevice(d){
$('#connect').innerHTML="Подключен к "+d.name;
device.dev = d;
device.dev.ongattserverdisconnected = function(){$('#connect').innerHTML="Соединение";device = {};writer = null;$('#device').style.display = "none";};
$('#device').style.display = "block";
}
function update(info){
Object.assign(deviceInfo,info);
for(k in info){var el = $('#'+k); if(el!=undefined)el[typeof info[k] == "boolean"?"checked":"innerHTML"] = info[k]};
}
if(Object.assign == undefined)Object.assign = function() {var o = {};for(var i=0; i < arguments.length; i += 1) {var obj = arguments[i],keys = Object.keys(obj);for(var j=0; j < keys.length; j += 1)o[keys[j]] = obj[keys[j]]}return o};
function hex_string(data){return Array.from(data).map(x=>x.toString(16).padStart(2, '0').toUpperCase()).join("-");}
function crc8(data){let crc=0xFF;for(var i=0;i<data.length;i++){crc^=data[i]&0xFF;for(var j=0;j<8;j++)if(crc & 1){crc>>=1;crc^=0xb8}else{crc>>=1}}return crc & 0xFFFF;}
function log(msg){$("#data").value=msg+"\n"+$("#data").value;}
function showConsole(x){$('#data').style.display = x?"block":"none";}
var url = x=>URL.createObjectURL(x);
function main(){
	if(navigator.bluetooth!=undefined){
		navigator.bluetooth.requestDevice({"optionalServices":['0000fff0-0000-1000-8000-00805f9b34fb'],"acceptAllDevices": true}).then(device=>device.gatt.connect())
		.then(server=>{setDevice(server.device);return server.getPrimaryService("0000fff0-0000-1000-8000-00805f9b34fb")})
		.then(service=>service.getCharacteristic("0000fff3-0000-1000-8000-00805f9b34fb"))
		.then(characterisristic=>{
			writer = characterisristic;
			log("подключен к "+characterisristic);
			return characterisristic.service;
		})
		.catch(error=>{console.error(error);});
	}
}
function send(info){
	Object.assign(deviceInfo,info);
	if(writer!=null){
		console.log(info);
		Object.keys(info).filter(x=>cmds.hasOwnProperty(x)).forEach(x=>{
			var packet = new Uint8Array(cmds[x](info[x]));
			log("<< "+hex_string(packet)+"   "+JSON.stringify(info));
			writer.writeValueWithoutResponse(packet);
		});
	}
}



</script>
<style>
body {
	margin:0;
	background:#FFFFFF;
	font-family: Helvetica, Arial, sans-serif;
}
#menu {width:auto;display:block;text-align:left;line-height:1.2;}
#menu ul {display:block;margin:0;padding:0;position:relative;width:auto;font-size:0;text-align:left;color:#EEE;background-color:#333;border:transparent;list-style:none;z-index:999999990;border-radius: 3px;}
#menu li {display:inline-block;position:relative;font-size:0;margin:0;padding:0;}
#menu >ul>li>span, #menu >ul>li>a {font-size:12px;color:inherit;text-decoration:none;padding:10px 15px;font-weight:400;text-transform:uppercase;letter-spacing:2px;display:block;position:relative;transition:all 0.3s;}
#menu li:hover > span, #menu li:hover > a {color:#333;background-color:#F3F3F3;}
#menu .smenu {text-align:left;left:0;color: #333;background-color:#F3F3F3;border:none;position:absolute;box-shadow: 0 4px 8px rgba(0,0,0,0.3);display:none;opacity:0;cursor:default;}
#menu .smenu li {display: block;}
#menu .smenu li > span, #menu .smenu li > a {font-size:14px;font-weight:400;font-family:inherit;margin:0;padding:8px 20px; display:block;color:inherit;text-decoration:none;}
#menu .smenu li:hover > span, #menu .smenu li:hover > a{color:#333;background-color:#DDD;}
#menu .smenu li > .smenu.right0 {left:auto;right:100%;}
#menu li:hover > .smenu {display:block;opacity:1;z-index:1;}
#menu .smenu li > .smenu {left:100%; right:auto;top:0;}
#menu ul.smenu {min-width:240px;}
#menu div.smenu {text-align:center;}
#menu .arrow {color:inherit;border-style:solid; border-width:2px 2px 0 0; padding:4px; transform:rotate(135deg);margin-top:-8.5px;margin-left:4px;position:relative;display: inline-block;width: 0;height: 0;vertical-align:middle;overflow:hidden;}
#menu .smenu .arrow {transform:rotate(45deg);top:50%;margin-top:-6px;position:absolute;left:auto;right:20px;}
@keyframes topItemAnimation {from {opacity: 0; transform:translate3d(0, -60px, 0);} to {opacity: 1; transform:translate3d(0, 0, 0);}}
#menu li a {animation:none;}
#menu.active li a { animation: topItemAnimation 0.5s cubic-bezier(.16,.84,.44,1) 0.083s backwards;}
#menu.active li:nth-of-type(1) a { animation: topItemAnimation 0.5s cubic-bezier(.16,.84,.44,1) 0.5s backwards;}
#menu.active li:nth-of-type(2) a { animation: topItemAnimation 0.5s cubic-bezier(.16,.84,.44,1) 0.41s backwards;}
#menu.active li:nth-of-type(3) a { animation: topItemAnimation 0.5s cubic-bezier(.16,.84,.44,1) 0.33s backwards;}
#menu.active li:nth-of-type(4) a { animation: topItemAnimation 0.5s cubic-bezier(.16,.84,.44,1) 0.25s backwards;}
#menu.active li:nth-of-type(5) a { animation: topItemAnimation 0.5s cubic-bezier(.16,.84,.44,1) 0.16s backwards;}@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { #menu.active li a{animation:none!important;}}
.switch input[type=checkbox]{height:0;width:0;visibility:hidden;}
.switch label{cursor: pointer;text-indent: -9999px;width: 40px;height:20px;background:grey;display:block;border-radius:20px;position:relative;}
.switch label:after {content:'';position:absolute;top:1px;left:1px;width:18px;height:18px;background:#fff;border-radius:18px;transition: 0.3s;}
.switch input:checked + label {background: #bada55;}
.switch input:checked + label:after {left: calc(100% - 1px);transform: translateX(-100%);}
.switch label:active:after {width: 26px;}
.param {font-size: 28px;padding: 10px;margin: 20px;border: 1px dotted #555;border-radius: 10px;}
.data {font-size: 28px;padding: 10px;}
.param .switch {float: right;}
#params { float: left; padding: 20px }
#data {position:absolute;bottom: 0px;left:0px;width: 100vw;height: 120px;}
</style>
</head>
<body>
<div id="menu">
	<ul>
		<li>
			<span>Устройство <i class="arrow"></i></span>
			<ul class="smenu">
				<li><a href="javascript:main()" id="connect">Соединение</a></li>
				<li><span>Свет <i class="arrow"></i></span>
					<ul class="smenu">
						<li><a href="javascript:send({on:1})">Включить</a></li>
						<li><a href="javascript:send({off:1})">Отключить</a></li>
					</ul>
				</li>
				<li><span>Цвет <input id="color" type="color" value="#ffffff" onchange="send({color:this.value})"/><i class="arrow"></i></span>
					<ul class="smenu">
						<li><a href="javascript:send({color:'#ff0000'})">Красный</a></li>
						<li><a href="javascript:send({color:'#00ff00'})">Зеленый</a></li>
						<li><a href="javascript:send({color:'#0000ff'})">Синий</a></li>
					</ul>
				</li>
				<li><span>Яркость <i class="arrow"></i></span>
					<ul class="smenu">
						<li><a href="javascript:send({bright:0})">10%</a></li>
						<li><a href="javascript:send({bright:10})">20%</a></li>
						<li><a href="javascript:send({bright:20})">30%</a></li>
						<li><a href="javascript:send({bright:30})">40%</a></li>
						<li><a href="javascript:send({bright:40})">50%</a></li>
						<li><a href="javascript:send({bright:100})">100%</a></li>
					</ul>
				</li>
				<li><span>Скорость <i class="arrow"></i></span>
					<ul class="smenu">
						<li><a href="javascript:send({speed:0})">10%</a></li>
						<li><a href="javascript:send({speed:10})">20%</a></li>
						<li><a href="javascript:send({speed:20})">30%</a></li>
						<li><a href="javascript:send({speed:30})">40%</a></li>
						<li><a href="javascript:send({speed:40})">50%</a></li>
						<li><a href="javascript:send({speed:64})">100%</a></li>
					</ul>
				</li>
				<li><span>Эффект <i class="arrow"></i></span>
					<ul class="smenu">
						<li><a href="javascript:send({effect:135})">3 цвета мигают</a></li>
						<li><a href="javascript:send({effect:136})">7 цветов мигают</a></li>
						<li><a href="javascript:send({effect:137})">3 цвета плавно</a></li>
						<li><a href="javascript:send({effect:138})">7 цветов плавно</a></li>
						<li><a href="javascript:send({effect:139})">красный плавно</a></li>
						<li><a href="javascript:send({effect:140})">зеленый плавно</a></li>
						<li><a href="javascript:send({effect:141})">синий плавно</a></li>
						<li><a href="javascript:send({effect:142})">желтый плавно</a></li>
						<li><a href="javascript:send({effect:143})">голубой плавно</a></li>
						<li><a href="javascript:send({effect:144})">пурпурный плавно</a></li>
						<li><a href="javascript:send({effect:145})">белый плавно</a></li>
						<li><a href="javascript:send({effect:146})">красный-зеленый плавно</a></li>
						<li><a href="javascript:send({effect:147})">красный-синий плавно</a></li>
						<li><a href="javascript:send({effect:148})">зеленый-синий плавно</a></li>
						<li><a href="javascript:send({effect:149})">7 цветов строб</a></li>
						<li><a href="javascript:send({effect:150})">красный строб</a></li>
						<li><a href="javascript:send({effect:151})">зеленый строб</a></li>
						<li><a href="javascript:send({effect:152})">синий строб</a></li>
						<li><a href="javascript:send({effect:153})">желтый строб</a></li>
						<li><a href="javascript:send({effect:154})">голубой строб</a></li>
						<li><a href="javascript:send({effect:155})">пуррурный строб</a></li>
						<li><a href="javascript:send({effect:156})">белый строб</a></li>
					</ul>
				</li>
				<li><span>Консоль отладки <i class="arrow"></i></span>
					<ul class="smenu">
						<li><a href="javascript:showConsole(false)">Скрыть</a></li>
						<li><a href="javascript:showConsole(true)">Показать</a></li>
					</ul>
				</li>
			</ul>
		</li>
	</ul>
</div>
<div id="device" style="display:none;">
<input type="color" value="#ffffff" onchange="send({color:this.value})"/><br>
<select onchange="send({effect:this.value})">
	<option value="135">3 цвета мигают</option>
	<option value="136">7 цветов мигают</option>
	<option value="137">3 цвета плавно</option>
	<option value="138">7 цветов плавно</option>
	<option value="139">красный плавно</option>
	<option value="140">зеленый плавно</option>
	<option value="141">синий плавно</option>
	<option value="142">желтый плавно</option>
	<option value="143">голубой плавно</option>
	<option value="144">пурпурный плавно</option>
	<option value="145">белый плавно</option>
	<option value="146">красный-зеленый плавно</option>
	<option value="147">красный-синий плавно</option>
	<option value="148">зеленый-синий плавно</option>
	<option value="149">7 цветов строб</option>
	<option value="150">красный строб</option>
	<option value="151">зеленый строб</option>
	<option value="152">синий строб</option>
	<option value="153">желтый строб</option>
	<option value="154">голубой строб</option>
	<option value="155">пуррурный строб</option>
	<option value="156">белый строб</option>
</select>
</div>
<textarea id="data" style="display: none;" rows=20 cols=50></textarea>

</body>
</html>